﻿#include "CastleGate.h"
#include "../../../Shared/Data/Stat.h"
#include "../../MessageQueue.h"
#include "../../MirEnvir/Envir.h"
#include "../../Settings.h"

using namespace Server::MirDatabase;
using namespace Server::MirEnvir;
namespace S = ServerPackets;

namespace Server::MirObjects::Monsters
{

    bool CastleGate::getCanAttack() const
    {
        return false;
    }

    bool CastleGate::getCanMove() const
    {
        return false;
    }

    bool CastleGate::getBlocking() const
    {
        return Closed && MonsterObject::getBlocking();
    }

    CastleGate::CastleGate(MonsterInfo *info) : MonsterObject(info)
    {
        Closed = true;
    }

    void CastleGate::Spawned()
    {
        MonsterObject::Spawned();

        if (BlockArray.empty())
        {
            return;
        }

        MonsterInfo *bInfo = new MonsterInfo();
        bInfo->Image = Monster::EvilMirBody;
        bInfo->CanTame = false;
        bInfo->CanPush = false;
        bInfo->AutoRev = false;

        bInfo->Stats[Stat::HP] = this->Stats[Stat::HP];

        for (auto block : BlockArray)
        {
            BlockingObject *b = new BlockingObject(this, bInfo);
            BlockingObjects.push_back(b);

            Point tempVar(this->getCurrentLocation()->X + block->X, this->getCurrentLocation()->Y + block->Y);
            if (!b->Spawn(this->getCurrentMap(), &tempVar))
            {
                getMessageQueue()->EnqueueDebugging(std::string::Format("{3} blocking mob not spawned at {0} {1}:{2}", getCurrentMap()->Info->FileName, block->X, block->Y, Info->Name));
            }

//C# TO C++ CONVERTER TODO TASK: A 'delete b' statement was not added since b was passed to a method or constructor. Handle memory management manually.
        }

//C# TO C++ CONVERTER TODO TASK: A 'delete bInfo' statement was not added since bInfo was passed to a method or constructor. Handle memory management manually.
    }

    void CastleGate::ProcessAI()
    {
        MonsterObject::ProcessAI();

        if (!Closed && CloseTime > 0 && CloseTime < getEnvir()->getTime())
        {
            CloseDoor();
            CloseTime = 0;
        }
    }

    void CastleGate::ProcessSearch()
    {
        if (getEnvir()->getTime() < SearchTime)
        {
            return;
        }

        SearchTime = getEnvir()->getTime() + SearchDelay;

        if (Closed && AutoOpen)
        {
            auto nearby = FindAllNearby(4, getCurrentLocation());

            for (int i = 0; i < nearby.size(); i++)
            {
                if (nearby[i]->getRace() != ObjectType::Player)
                {
                    continue;
                }
                PlayerObject *player = static_cast<PlayerObject*>(nearby[i]);

                if (player->MyGuild == nullptr || player->MyGuild->Conquest == nullptr || player->MyGuild->Conquest != Conquest || player->WarZone)
                {
                    continue;
                }

                OpenDoor();
                CloseTime = getEnvir()->getTime() + (Settings::Second * 10);
                break;
            }
        }
    }

    void CastleGate::Turn(MirDirection dir)
    {
    }

    bool CastleGate::Walk(MirDirection dir)
    {
        return false;
    }

    bool CastleGate::IsAttackTarget(MonsterObject *attacker)
    {
        if (attacker->Master != nullptr && attacker->Master->getRace() == ObjectType::Player)
        {
            PlayerObject *owner = static_cast<PlayerObject*>(attacker->Master);

            if (owner->MyGuild != nullptr && owner->MyGuild->Conquest != nullptr && owner->MyGuild->Conquest == Conquest)
            {
                return false;
            }
        }

        return Closed && MonsterObject::IsAttackTarget(attacker);
    }

    bool CastleGate::IsAttackTarget(PlayerObject *attacker)
    {
        if (attacker->MyGuild != nullptr && attacker->MyGuild->Conquest != nullptr && attacker->MyGuild->Conquest == Conquest)
        {
            return false;
        }

        return Closed && MonsterObject::IsAttackTarget(attacker);
    }

    void CastleGate::ProcessRoam()
    {
    }

    Packet *CastleGate::GetInfo()
    {
        return MonsterObject::GetInfo();
    }

    void CastleGate::Die()
    {
        ActiveDoorWall(false);
        MonsterObject::Die();
    }

    int CastleGate::Attacked(PlayerObject *attacker, int damage, DefenceType type, bool damageWeapon)
    {
        return MonsterObject::Attacked(attacker, damage, type, damageWeapon);
    }

    void CastleGate::ActiveDoorWall(bool closed)
    {
        for (auto obj : BlockingObjects)
        {
            if (obj == nullptr)
            {
                continue;
            }
            if (closed)
            {
                obj->Show();
            }
            else
            {
                obj->Hide();
            }
        }
    }
}
